#include "stdafx.h"

#include <time.h>

#include "resource.h"

#include "MainDlg.h"

#include "Registry.h"

#include "random.h"

CAppModule _Module;

int Run(LPTSTR /*lpstrCmdLine*/ = NULL, int nCmdShow = SW_SHOWDEFAULT)
{
	CMessageLoop theLoop;
	_Module.AddMessageLoop(&theLoop);

	CMainDlg dlgMain;

	if (dlgMain.Create(NULL) == NULL)
	{
		ATLTRACE(_T("Main dialog creation failed!\n"));
		return 0;
	}

	dlgMain.ShowWindow(nCmdShow);

	int nRet = theLoop.Run();

	_Module.RemoveMessageLoop();
	return nRet;
}

/**
 *
 *
 */
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
	UINT  num = 0;          // number of image encoders
	UINT  size = 0;         // size of the image encoder array in bytes

	ImageCodecInfo* pImageCodecInfo = NULL;

	GetImageEncodersSize(&num, &size);

	if (size == 0)
		return -1;  // Failure

	pImageCodecInfo = (ImageCodecInfo*)(malloc(size));

	if (pImageCodecInfo == NULL)
		return -1;  // Failure

	GetImageEncoders(num, size, pImageCodecInfo);

	for (UINT j = 0; j < num; ++j)
	{
		if ( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
		{
			*pClsid = pImageCodecInfo[j].Clsid;
			free(pImageCodecInfo);
			return j;  // Success
		}
	}

	free(pImageCodecInfo);

	return -1;  // Failure
}

/**
 *
 *
 */
int ChangeWallpaper()
{
	randomizeMT();

	TCHAR szFolder[MAX_PATH] = {0};
	// get default pictures folder
	SHGetFolderPath(NULL, CSIDL_MYPICTURES, NULL, 0, szFolder);

	//
	CRegistry reg(HKEY_CURRENT_USER, _T("Software\\NRG\\WallpaperSwitcher"));
	CString strFolder = reg.ReadString(_T("Folder"), szFolder);

	strFolder += _T("\\");
	//
	CAtlArray<CString> arrFiles;
	WIN32_FIND_DATA findData = {0};
	HANDLE hFindFile = FindFirstFile(strFolder + _T("*.jpg"), &findData);

	if (hFindFile != INVALID_HANDLE_VALUE)
	{
		do
		{
			arrFiles.Add(strFolder + findData.cFileName);

		}
		while (FindNextFile(hFindFile, &findData));

		FindClose(hFindFile);
	}

	//
	if (arrFiles.GetCount() > 0)
	{
		CString strNewWallpaper = arrFiles.GetAt(randomMT((ULONG)arrFiles.GetCount()));

		// load bitmap
		Bitmap bmp(strNewWallpaper, FALSE);

		// create desktop-compatible graphics
		Graphics graphics(GetDC(GetDesktopWindow()));

		// create compatible bitmap
		Bitmap bmpNew(GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), &graphics);

		// create graphics to draw on image
		Graphics imageGraphics(&bmpNew);

		// draw image
		imageGraphics.DrawImage(&bmp, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));

		// create wallpaper file name
		CString strTemp = strFolder + _T("current.bmp");

		// Get the CLSID of the BMP encoder.
		CLSID encoderClsid;
		GetEncoderClsid(L"image/bmp", &encoderClsid);

		// save wallpaper
		Status stat = bmpNew.Save(strTemp, &encoderClsid, NULL);

		if (stat == Ok)
		{
			// set wallpaper
			const TCHAR* path = strTemp.GetString();

			if (!SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, (PVOID)path, TRUE))
			{
				DWORD dw = GetLastError();
			}

			// set wallpaper parameters
			CRegistry reg2(HKEY_CURRENT_USER, _T("Control Panel\\Desktop"));

			reg2.WriteDWORD(_T("WallpaperStyle"), 2);

			reg2.WriteDWORD(_T("TileWallpaper"), 0);
		}
	}

	return 0;
}

/**
 *
 *
 */
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow)
{
	//HRESULT hRes = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
	HRESULT hRes = ::CoInitialize(NULL);
	ATLASSERT(SUCCEEDED(hRes));

	// this resolves ATL window thunking problem when Microsoft Layer for Unicode (MSLU) is used
	::DefWindowProc(NULL, 0, 0, 0L);

	AtlInitCommonControls(ICC_BAR_CLASSES);	// add flags to support other controls

	hRes = _Module.Init(NULL, hInstance);
	ATLASSERT(SUCCEEDED(hRes));

	AtlAxWinInit();

	// Initialize GDI+.
	GdiplusStartupInput gdiplusStartupInput;
	ULONG_PTR           gdiplusToken;
	GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

	// Parse command line, register or unregister or run the server
	int nRet = 0;
	TCHAR szTokens[] = _T("-/");
	bool bRun = true;
	bool bAutomation = false;

	LPCTSTR lpszToken = _Module.FindOneOf(::GetCommandLine(), szTokens);

	while (lpszToken != NULL)
	{
		CString strToken = lpszToken;
		strToken.MakeLower();

		if (strToken == _T("startup"))
		{
			nRet = ChangeWallpaper();
			bRun = false;
			break;
		}

		lpszToken = _Module.FindOneOf(lpszToken, szTokens);
	}

	if (bRun)
	{
		int nRet = Run(lpstrCmdLine, nCmdShow);
	}

	GdiplusShutdown(gdiplusToken);

	_Module.Term();

	::CoUninitialize();

	return nRet;
}
